﻿namespace AbpCodeGenerater.Core
{
    public static class AbpSolutionExtension
    {
        public static string[] ExcludedFilesEndWith = new string[] {
            "Repository.cs",
            "Manager.cs",
            "DomainModule.cs",
            "DbProperties.cs",
            "Provider.cs",
            "Settings.cs",
            "DataSeedContributor.cs",
        };

        public static TreeNode ToTreeNode(this AbpSolution sln)
        {
            var solutionNode = new TreeNode();
            solutionNode.Tag = sln;
            solutionNode.Text = sln.Name;

            foreach (var domainProject in sln.DomainProjects)
            {
                solutionNode.Nodes.Add(domainProject.ToTreeNode());
            }

            return solutionNode;
        }

        public static TreeNode ToTreeNode(this AbpProject abpProject)
        {
            var projectNode = new TreeNode();
            projectNode.Tag = abpProject;
            projectNode.Text = abpProject.Name;

            if (abpProject.FullPath == null) throw new Exception("未能正确加载项目目录");
            var directoryInfo = new DirectoryInfo(abpProject.FullPath);

            foreach (var childDirectoryInfo in directoryInfo.GetDirectories())
            {
                if (new[] { "obj", "bin" }.Contains(childDirectoryInfo.Name)) continue;

                var directoryNode = LoadAbpDirectory(abpProject, childDirectoryInfo);
                if (directoryNode.Nodes.Count <= 0) continue;
                projectNode.Nodes.Add(directoryNode);
            }

            foreach (var fileInfo in directoryInfo.GetFiles().Where(x => x.Extension == ".cs" && ExcludedFilesEndWith.All(ends => !x.Name.EndsWith(ends))))
            {
                projectNode.Nodes.Add(LoadAbpFiles(abpProject, fileInfo));
            }

            return projectNode;
        }

        private static TreeNode LoadAbpDirectory(AbpProject abpProject, DirectoryInfo directoryInfo, bool expand = false)
        {
            var node = new TreeNode();
            node.Text = directoryInfo.Name;
            if (expand) node.Expand();

            foreach (var childDirectoryInfo in directoryInfo.GetDirectories())
            {
                if (new[] { "obj", "bin" }.Contains(childDirectoryInfo.Name)) continue;

                var directoryNode = LoadAbpDirectory(abpProject, childDirectoryInfo);
                if (directoryNode.Nodes.Count <= 0) continue;
                node.Nodes.Add(directoryNode);
            }

            foreach (var childFileInfo in directoryInfo.GetFiles().Where(x => x.Extension == ".cs" && ExcludedFilesEndWith.All(ends => !x.Name.EndsWith(ends))))
            {
                node.Nodes.Add(LoadAbpFiles(abpProject, childFileInfo));
            }

            return node;
        }

        private static TreeNode LoadAbpFiles(AbpProject abpProject, FileInfo fileInfo, bool expand = false)
        {
            var abpClass = new AbpClass();
            abpClass.FileName = fileInfo.Name;
            abpClass.Name = Path.GetFileNameWithoutExtension(fileInfo.Name);
            abpClass.FullPath = fileInfo.FullName;
            abpClass.AbpProject = abpProject;

            var fileNode = new TreeNode();
            fileNode.Tag = abpClass;
            fileNode.Text = abpClass.FileName;
            return fileNode;
        }
    }
}
